package com.witmore.skyline.web.service.third.yjx.client;

import com.witmore.skyline.web.controller.enums.WitmoreErrorCode;
import com.witmore.skyline.web.controller.vo.param.CameraParamVO;
import com.witmore.skyline.web.exception.WitmoreException;
import com.witmore.skyline.web.service.third.tplink.ApiTPClient;
import com.witmore.skyline.web.service.third.tplink.ApiVmsStreamClient;
import com.witmore.skyline.web.service.third.tplink.dto.TpAkAndSkDTO;
import com.witmore.skyline.web.service.third.yjx.dto.CameraLiveDTO;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class CameraUrlCache {

    private static final ConcurrentHashMap<String, CameraCacheInfo> cameraUrlCache = new ConcurrentHashMap<>();

    /**
     * 缓存 过期时间 默认10分钟
     */
    private static final long EXPIRE_TIME = 60000 * 10;


    /**
     * 根据 cameraSn 获取url的方法，首先从缓存中查找
     */
    public static synchronized CameraLiveDTO getCameraUrl(CameraParamVO cameraParamVO) {
        String cameraSn = cameraParamVO.getCameraSn();
        if (isCameraUrlCacheExpired(cameraSn)) {
            // 过期了 就刷新缓存
            return refreshCameraUrlCacheNew(cameraParamVO);
        }
        CameraCacheInfo cacheInfo = cameraUrlCache.get(cameraSn);
        return cacheInfo.getCameraLiveCache();
    }



    /**
     * 刷新缓存
     */
    private static CameraLiveDTO refreshCameraUrlCacheNew(CameraParamVO cameraParamVO) {
        CameraLiveDTO cameraLiveDTO = new CameraLiveDTO();
        try {
            String sdkStreamUrl = ApiVmsStreamClient.requestStreamUrl(cameraParamVO);
            // 获取临时SK和AK
            TpAkAndSkDTO tempApplicationApiCredential = ApiTPClient.createTempApplicationApiCredential(cameraParamVO.getExpireTime());
            if (tempApplicationApiCredential == null){
                throw new WitmoreException(WitmoreErrorCode.THIRD_PARTY_API_ERROR, "获取临时SK和AK失败");
            }
            cameraLiveDTO.setAk(tempApplicationApiCredential.getTempAk());
            cameraLiveDTO.setSk(tempApplicationApiCredential.getTempSk());
            cameraLiveDTO.setExpireTime(tempApplicationApiCredential.getExpireTime());
            cameraLiveDTO.setCreateTime(tempApplicationApiCredential.getCreateTime());
            cameraLiveDTO.setUrl(sdkStreamUrl);
            cameraLiveDTO.setCameraSn(cameraParamVO.getCameraSn());
        } catch (Exception e) {
            log.error("API 获取摄像头播放地址失败 ！ 刷新缓存失败，cameraSn-->{},失败原因:", cameraParamVO.getCameraSn(), e);
            throw new WitmoreException(WitmoreErrorCode.THIRD_PARTY_API_ERROR, e.getMessage());
        }
        cameraUrlCache.put(cameraParamVO.getCameraSn(), new CameraCacheInfo(cameraLiveDTO, System.currentTimeMillis() + EXPIRE_TIME));
        return cameraLiveDTO;
    }

    /**
     * 检查 CameraUrlCache 缓存 是否过期
     */
    private static boolean isCameraUrlCacheExpired(String cameraSn) {
        if (CollectionUtils.isEmpty(cameraUrlCache)) {
            return true;
        }
        CameraCacheInfo cacheInfo = cameraUrlCache.get(cameraSn);
        return cacheInfo == null || cacheInfo.getCameraLiveCache() == null
                || cacheInfo.isExpired();
    }

    /**
     * CameraCacheInfo 信息类，包含CameraLiveDTO和过期时间
     */
    @Data
    static class CameraCacheInfo {
        private CameraLiveDTO cameraLiveCache;
        private long expiryTime;

        public CameraCacheInfo(CameraLiveDTO cameraLiveCache, long expiryTime) {
            this.cameraLiveCache = cameraLiveCache;
            this.expiryTime = expiryTime;
        }

        public boolean isExpired() {
            return System.currentTimeMillis() > expiryTime;
        }
    }
}
